package com.jiaok.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiaok.comm.CommonResponse;
import com.jiaok.entity.LoginUser;
import com.jiaok.entity.SysUser;
import com.jiaok.model.param.UserParam;
import com.jiaok.service.ILoginService;
import com.jiaok.service.ISysUserService;
import com.jiaok.utils.JwtUtil;
import com.jiaok.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author jiaok
 * @Date 2023/5/8 16:38
 */
@Service
@Slf4j
public class LoginServiceImpl  implements ILoginService {

    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private RedisCache redisCache;

    @Resource
    private ISysUserService iSysUserService;


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 处理用户登录的实际逻辑
     * @param userParam
     * @return
     */
    @Override
    public CommonResponse login(UserParam userParam) {
//       注入 AuthenticationManager  调用authenticate 方法进行登录认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userParam.getUserName(), userParam.getPassword());

        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//       认证没有通过，给出提示-----> 返回值为null，则说明认证未通过
        if (Objects.isNull(authenticate)){
            throw  new RuntimeException("登录失败");
        }
//       认证通过，使用userid 生成一个jwt
        User loginUser = (User) authenticate.getPrincipal();
        String username = loginUser.getUsername();
        SysUser user = iSysUserService.getOne(new QueryWrapper<SysUser>().eq("user_name", username));
//        if (!loginUser.getAuthorities().isEmpty()) {
//            ((List<GrantedAuthority>) );
//        }
        Collection<GrantedAuthority> authorities = loginUser.getAuthorities();
        ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        grantedAuthorities.addAll(authorities);
        user.setGrantedAuthorities(grantedAuthorities);
        String token = JwtUtil.createJWT(user.getId().toString());
        HashMap<String, String> map = new HashMap<>();
        map.put(user.getId().toString(),token);
//       讲完整的用户信息存储在redis中
        redisCache.setCacheObject("USERINFO:"+user.getId().toString(),user);
        return  CommonResponse.ok("登录成功",map);

    }

    @Override
    public CommonResponse loginOut() {
        //获取SecurityContextHolder中的用户信息
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        SysUser user = (SysUser) authentication.getPrincipal();
//        删除redis中的用户信息，这样在前面过滤器中获取不到用户信息，就不会再继续向下运行了
        Long id = user.getId();
        Boolean delete = stringRedisTemplate.delete("USERINFO:" + id.toString());
        log.info("---------退出登录，删除redis内的用户信息");

        return new CommonResponse(200,"退出成功");
    }
}
